﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using zeus.Core;
using zeus.Core.RepositoryInterfaces;
using SharpArch.Data.NHibernate;
using NHibernate;
using NHibernate.Transform;
using NHibernate.Criterion;

namespace zeus.Data
{
    public class UnidadRepository : Repository<Unidad>, IUnidadRepository
    {

        public IList<Unidad> GetByUsuario(int UsuarioID)
        {
            IList<Unidad> unidades = Session.CreateSQLQuery("select * from unidad inner join usuario_unidad on unidad.und_id = usuario_unidad.und_id where usr_id = :usr_id")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("usr_id", UsuarioID)
                    .List<Unidad>();

            IList<Unidad> unidadesGrupo = Session.CreateSQLQuery(@"select unidad.* 
                                                                     from grupo_unidad inner join grupo on grupo_unidad.grp_id = grupo.grp_id 
                                                                            inner join grupo_usuario on grupo_usuario.grp_id = grupo.grp_id
                                                                            inner join unidad on unidad.und_id = grupo_unidad.und_id
                                                                    where usr_id = :usr_id")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("usr_id", UsuarioID)
                    .List<Unidad>();

            IList<Unidad> total = new List<Unidad>();

            unidades.ToList().ForEach(p => total.Add(p));
            unidadesGrupo.ToList().ForEach(p => total.Add(p));

            return total.Distinct().ToList();

        }
                
        public IList<Unidad> GetDisponiblesByGrupo(int ClienteID, Grupo grupo)
        {
            return Session.CreateSQLQuery("select * from unidad where cli_id = :cli_id and not exists (select 1 from grupo_unidad where grp_id = :grp_id and unidad.und_id = grupo_unidad.und_id)")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("cli_id", ClienteID)
                    .SetInt32("grp_id", grupo.Id)
                    .List<Unidad>();
        }

        public IList<Unidad> GetSeleccionadosByGrupo(int ClienteID, Grupo grupo)
        {
            return Session.CreateSQLQuery("select * from unidad where cli_id = :cli_id and exists (select 1 from grupo_unidad where grp_id = :grp_id and unidad.und_id = grupo_unidad.und_id)")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("cli_id", ClienteID)
                    .SetInt32("grp_id", grupo.Id)
                    .List<Unidad>();
        }

        public IList<Unidad> GetDisponiblesByPlan(int ClienteID, PlanCliente planCliente)
        {
            return Session.CreateSQLQuery("select * from unidad where cli_id = :cli_id and not exists (select 1 from plan_disponible where placli_id = :placli_id and unidad.und_id = plan_disponible.und_id)")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("cli_id", ClienteID)
                    .SetInt32("placli_id", planCliente.Id)
                    .List<Unidad>();
        }

        public IList<Unidad> GetSeleccionadosByPlan(int ClienteID, PlanCliente planCliente)
        {
            return Session.CreateSQLQuery("select * from unidad where cli_id = :cli_id and exists (select 1 from plan_disponible where placli_id = :placli_id and unidad.und_id = plan_disponible.und_id)")
                    .AddEntity(typeof(Unidad))
                    .SetInt32("cli_id", ClienteID)
                    .SetInt32("placli_id", planCliente.Id)
                    .List<Unidad>();
        }

        public  int  GetNumeroUnidad(int id)
        {
            return Session.CreateSQLQuery("select und_numero from unidad  where und_id = " + id.ToString() + "")
                .SetFirstResult(0)
                .SetMaxResults(1)
                .UniqueResult<int>();
               
        }


        /// <summary>
        /// Recuperar las unidades por nombre
        /// </summary>
        /// <param name="nombre"></param>
        /// <returns></returns>
        public IList<Unidad> GetByNombre(string nombre, int clienteId)
        {
            return Session.CreateCriteria<Unidad>()
                .Add(Restrictions.InsensitiveLike("Nombre", "%" + nombre + "%"))
                .Add(Restrictions.Eq("CodigoCliente", clienteId))
                .List<Unidad>();
        }

        /// <summary>
        /// Recuperar las unidades por codigo del cliente
        /// </summary>
        /// <param name="clienteId"></param>
        /// <returns></returns>
        public IList<Unidad> GetByCliente(int clienteId)
        {
            return Session.CreateCriteria<Unidad>()
                .Add(Restrictions.Eq("CodigoCliente", clienteId))
                .List<Unidad>();
        }

        public IList<Unidad> GetByClienteUbicacion()
        {

            return Session.CreateQuery("from Unidad u, Ubicacion b where u.Id = b.CodigoUnidad")
              .SetFirstResult(0)
              .SetMaxResults(20)
              .List<Unidad>();

        }

    }
}
